package com.zxy.leetcode._00400_00499._00400_00409;

import java.util.Deque;
import java.util.LinkedList;

/**
 * https://leetcode-cn.com/problems/remove-k-digits/
 *
 * 移掉K位数字
 * 给定一个以字符串表示的非负整数 num，移除这个数中的 k 位数字，使得剩下的数字最小。
 *
 * 注意:
 * num 的长度小于 10002 且 ≥ k。
 * num 不会包含任何前导零。
 *
 * 标签：贪心、双向队列
 */
public class Test00402 {

    public static void main(String[] args) {
        Test00402 test = new Test00402();
        System.out.println(test.removeKdigits("1432219", 3));
        System.out.println(test.removeKdigits("10200", 1));
    }

    /*
    贪心策略：每次都拿到数字，让当前这个数字是最小的
     */
    public String removeKdigits(String num, int k) {
        if (k == 0) {
            return num;
        }
        if (num.length() == k) {
            return "0";
        }

        Deque<Character> deque = new LinkedList<>();
        char[] chars = num.toCharArray();
        int len = chars.length;
        // 保留的位数
        int remain = len - k;

        for (int i=0; i<len; i++) {
            if (deque.isEmpty()) {
                deque.add(chars[i]);
            }else if (deque.size() + (len-i) == remain) {
                // 剩余没判断的数字已经够最后保留的位数了，直接保存结束
                deque.add(chars[i]);
            }else if (chars[i] >= deque.getLast()) {
                // 当前数字较大，且位数还够，可以放入
                if (deque.size() < remain) {
                    deque.add(chars[i]);
                }
            }else {
                while (!deque.isEmpty() && deque.size() + (len-i) > remain && chars[i] < deque.getLast()) {
                    // 当前数字较小，删除前面较大的数字，但最多是当前剩下的全部放入
                    deque.removeLast();
                }
                deque.add(chars[i]);
            }
        }

        // 过滤前面的“0”
        boolean check0 = true;
        StringBuilder stringBuilder = new StringBuilder();
        for (char c : deque) {
            if (check0 && c == '0') {
                continue;
            }
            check0 = false;
            stringBuilder.append(c);
        }

        return stringBuilder.length() == 0 ? "0" : stringBuilder.toString();
    }

    /*
    官方的解法
    https://leetcode-cn.com/problems/remove-k-digits/solution/yi-diao-kwei-shu-zi-by-leetcode-solution/
     */
    public String removeKdigits2(String num, int k) {
        Deque<Character> deque = new LinkedList<Character>();
        int length = num.length();
        for (int i = 0; i < length; ++i) {
            char digit = num.charAt(i);
            while (!deque.isEmpty() && k > 0 && deque.peekLast() > digit) {
                deque.pollLast();
                k--;
            }
            deque.offerLast(digit);
        }

        for (int i = 0; i < k; ++i) {
            deque.pollLast();
        }

        StringBuilder ret = new StringBuilder();
        boolean leadingZero = true;
        while (!deque.isEmpty()) {
            char digit = deque.pollFirst();
            if (leadingZero && digit == '0') {
                continue;
            }
            leadingZero = false;
            ret.append(digit);
        }
        return ret.length() == 0 ? "0" : ret.toString();
    }
}
